using AdminSG3L.Applicaticn.Commands;
using AdminSG3L.Applicaticn.Dtos;
using AdminSG3L.Applicaticn.ServicesInterface;
using AdminSG3L.Domain.Entities;
using AdminSG3L.Domain.Repositories;
using Microsoft.Extensions.Configuration;
using AdminSG3L.Applicaticn.Utils;
using AdminSG3L.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace AdminSG3L.Applicaticn.Services;

public class AuthService(IRepository<AppUser> userRepository, IUserService userService, IConfiguration config, AdminDbContext dbContext) : IAuthService
{
    private readonly IRepository<AppUser> _userRepository = userRepository;
    private readonly IUserService _userService = userService;
    private readonly AdminDbContext _dbContext = dbContext;
    private readonly string _jwtSecret = config["Jwt:Secret"]
        ?? throw new InvalidOperationException("JWT密钥未配置，请在appsettings.json中设置Jwt:Secret");
    private readonly int _accessTokenExpireMinutes = int.TryParse(config["Jwt:AccessTokenExpireMinutes"], out var at) ? at : 30;
    private readonly int _refreshTokenExpireDays = int.TryParse(config["Jwt:RefreshTokenExpireDays"], out var rt) ? rt : 7;

    /// <summary>
    /// 获取用户完整信息（包括角色、权限、菜单）
    /// </summary>
    private async Task<UserInfoDto> GetUserCompleteInfoAsync(AppUser user)
    {
        // 获取用户的角色、权限和菜单
        var userWithRoles = await _dbContext.Users
            .Include(u => u.Roles)
                .ThenInclude(r => r.Permissions)
            .Include(u => u.Roles)
                .ThenInclude(r => r.Menus)
            .FirstOrDefaultAsync(u => u.Id == user.Id);

        Console.WriteLine($"用户 {user.Username} 查询结果:");
        Console.WriteLine($"- 用户是否找到: {userWithRoles != null}");
        Console.WriteLine($"- 角色数量: {userWithRoles?.Roles?.Count ?? 0}");

        if (userWithRoles?.Roles != null)
        {
            foreach (var role in userWithRoles.Roles)
            {
                Console.WriteLine($"  - 角色: {role.RoleName} ({role.RoleCode})");
                Console.WriteLine($"    权限数量: {role.Permissions?.Count ?? 0}");
                Console.WriteLine($"    菜单数量: {role.Menus?.Count ?? 0}");
            }
        }

        var roles = userWithRoles?.Roles?.Select(r => new RoleDto(
            r.Id,
            r.RoleName,
            r.RoleCode,
            r.Description
        )).ToArray() ?? [];

        var permissions = userWithRoles?.Roles?
            .SelectMany(r => r.Permissions)
            .Select(p => p.PermissionCode ?? "")
            .Where(code => !string.IsNullOrEmpty(code))
            .Distinct()
            .ToArray() ?? [];

        var menus = userWithRoles?.Roles?
            .SelectMany(r => r.Menus)
            .Select(m => new MenuDto(
                m.Id,
                m.MenuName,
                m.MenuCode,
                m.ParentId,
                m.Icon,
                m.Path,
                m.Description
            ))
            .DistinctBy(m => m.Id)
            .ToArray() ?? [];

        return new UserInfoDto(
            user.Id,
            user.Username,
            user.Email,
            user.Avatar,
            roles,
            permissions,
            menus
        );
    }

    public async Task<ApiResponse<TokenResponseDto>> LoginAsync(LoginDto dto)
    {
        var usernameError = FormValidator.ValidateUsername(dto.Username);
        if (usernameError != null)
            return ApiResponse<TokenResponseDto>.Fail(usernameError);

        // 登录时不验证密码格式，只检查是否为空
        if (string.IsNullOrWhiteSpace(dto.Password))
            return ApiResponse<TokenResponseDto>.Fail("密码不能为空");

        var user = (await _userRepository.GetAllAsync())
            .FirstOrDefault(u => u.Username == dto.Username);
        if (user == null)
        {
            return ApiResponse<TokenResponseDto>.Fail("用户不存在");
        }
        if (!user.IsActive)
        {
            return ApiResponse<TokenResponseDto>.Fail("用户已被禁用，无法登录");
        }
        if (!user.VerifyPassword(dto.Password))
        {
            return ApiResponse<TokenResponseDto>.Fail("密码错误");
        }
        // 生成AccessToken和RefreshToken
        var accessToken = Utils.JwtHelper.GenerateToken(user.Id.ToString(), user.Username, _jwtSecret, _accessTokenExpireMinutes);
        var refreshToken = Guid.NewGuid().ToString("N");
        var refreshExpire = DateTime.UtcNow.AddDays(_refreshTokenExpireDays);
        user.SetRefreshToken(refreshToken, refreshExpire);

        // 更新登录信息
        user.UpdateLoginInfo(); // 更新登录次数和最后登录时间

        await _userRepository.UpdateAsync(user);

        // 获取用户完整信息
        var userInfo = await GetUserCompleteInfoAsync(user);

        // 返回TokenResponseDto对象
        var tokenResponse = new TokenResponseDto(accessToken, refreshToken, userInfo);
        return ApiResponse<TokenResponseDto>.Success(tokenResponse, "登录成功");
    }

    public async Task<ApiResponse<TokenResponseDto>> RegisterAsync(RegisterDto dto)
    {
        var usernameError = FormValidator.ValidateUsername(dto.Username);
        if (usernameError != null)
            return ApiResponse<TokenResponseDto>.Fail(usernameError);
        var emailError = FormValidator.ValidateEmail(dto.Email);
        if (emailError != null)
            return ApiResponse<TokenResponseDto>.Fail(emailError);
        var passwordError = FormValidator.ValidatePassword(dto.Password);
        if (passwordError != null)
            return ApiResponse<TokenResponseDto>.Fail(passwordError);
        // 可选：邮箱验证码、图形验证码、协议等校验
        var existingUsers = await _userRepository.GetAllAsync();
        var exists = existingUsers.Any(u => u.Username == dto.Username || u.Email == dto.Email);
        if (exists)
        {
            return ApiResponse<TokenResponseDto>.Fail("用户名或邮箱已存在");
        }
        var user = AppUser.Create(
            null, // NickName
            dto.Username,
            dto.Password,
            dto.Email, // Email
            null, // Avatar
            null  // Description
        );
        // 查找普通用户角色（RoleCode = "user"）
        var normalRole = await _dbContext.Roles.FirstOrDefaultAsync(r => r.RoleCode == "regular_user");
        if (normalRole != null)
        {
            user.AddRole(normalRole);
        }
        // 生成RefreshToken
        var refreshToken = Guid.NewGuid().ToString("N");
        var refreshExpire = DateTime.UtcNow.AddDays(_refreshTokenExpireDays);
        user.SetRefreshToken(refreshToken, refreshExpire);
        await _userRepository.AddAsync(user);
        // 生成AccessToken
        var accessToken = Utils.JwtHelper.GenerateToken(user.Id.ToString(), user.Username, _jwtSecret, _accessTokenExpireMinutes);
        // 获取用户完整信息
        var userInfo = await GetUserCompleteInfoAsync(user);
        var tokenResponse = new TokenResponseDto(accessToken, refreshToken, userInfo);
        return ApiResponse<TokenResponseDto>.Success(tokenResponse, "注册成功");
    }

    public async Task<ApiResponse<TokenResponseDto>> RefreshTokenAsync(RefreshTokenDto dto)
    {
        var user = (await _userRepository.GetAllAsync())
            .FirstOrDefault(u => u.RefreshToken == dto.RefreshToken && u.RefreshTokenExpireAt > DateTime.UtcNow);
        if (user == null)
        {
            return ApiResponse<TokenResponseDto>.Fail("RefreshToken无效或已过期");
        }
        var accessToken = Utils.JwtHelper.GenerateToken(user.Id.ToString(), user.Username, _jwtSecret, _accessTokenExpireMinutes);
        var newRefreshToken = Guid.NewGuid().ToString("N");
        var refreshExpire = DateTime.UtcNow.AddDays(_refreshTokenExpireDays);
        user.SetRefreshToken(newRefreshToken, refreshExpire);
        await _userRepository.UpdateAsync(user);

        // 获取用户完整信息
        var userInfo = await GetUserCompleteInfoAsync(user);

        return ApiResponse<TokenResponseDto>.Success(new TokenResponseDto(accessToken, newRefreshToken, userInfo), "刷新成功");
    }

    public async Task<ApiResponse<bool>> VerifyIdentityAsync(ForgotPasswordVerifyDto dto)
    {
        var usernameError = FormValidator.ValidateUsername(dto.Username);
        if (usernameError != null)
            return ApiResponse<bool>.Fail(usernameError);
        var emailError = FormValidator.ValidateEmail(dto.Email);
        if (emailError != null)
            return ApiResponse<bool>.Fail(emailError);
        var emailCodeError = FormValidator.ValidateEmailCode(dto.EmailCode, dto.Email);
        if (emailCodeError != null)
            return ApiResponse<bool>.Fail(emailCodeError);
        var user = (await _userRepository.GetAllAsync())
            .FirstOrDefault(u => u.Username == dto.Username && u.Email == dto.Email);
        if (user == null)
        {
            return ApiResponse<bool>.Fail("用户或邮箱不正确");
        }
        // 邮箱验证码校验应在此处实现（略）
        return ApiResponse<bool>.Success(true, "身份验证成功");
    }

    public async Task<ApiResponse<bool>> VerifyUserAsync(ForgotPasswordVerifyUserDto dto)
    {
        var usernameError = FormValidator.ValidateUsername(dto.Username);
        if (usernameError != null)
            return ApiResponse<bool>.Fail(usernameError);
        var emailError = FormValidator.ValidateEmail(dto.Email);
        if (emailError != null)
            return ApiResponse<bool>.Fail(emailError);

        var user = (await _userRepository.GetAllAsync())
            .FirstOrDefault(u => u.Username == dto.Username && u.Email == dto.Email);
        if (user == null)
        {
            return ApiResponse<bool>.Fail("用户名或邮箱不正确");
        }

        return ApiResponse<bool>.Success(true, "用户信息验证成功");
    }

    public async Task<ApiResponse<bool>> ResetPasswordAsync(ResetPasswordDto dto)
    {
        // 验证新密码
        var passwordError = FormValidator.ValidatePassword(dto.NewPassword);
        if (passwordError != null)
            return ApiResponse<bool>.Fail(passwordError);

        // 验证邮箱验证码
        var emailCodeError = FormValidator.ValidateEmailCode(dto.EmailCode, dto.Email);
        if (emailCodeError != null)
            return ApiResponse<bool>.Fail(emailCodeError);

        // 查找用户
        var user = (await _userRepository.GetAllAsync())
            .FirstOrDefault(u => u.Username == dto.Username && u.Email == dto.Email);
        if (user == null)
        {
            return ApiResponse<bool>.Fail("用户名或邮箱不匹配");
        }

        // 使用 UserService 的重置密码方法确保数据一致性
        var resetResult = await _userService.ResetPasswordAsync(user.Id, dto.NewPassword);

        if (resetResult.IsSuccess)
        {
            return ApiResponse<bool>.Success(true, "密码重置成功");
        }
        else
        {
            return ApiResponse<bool>.Fail(resetResult.Message);
        }
    }

    public async Task<ApiResponse<bool>> RevokeRefreshTokenAsync(string refreshToken)
    {
        var user = (await _userRepository.GetAllAsync())
            .FirstOrDefault(u => u.RefreshToken == refreshToken);
        if (user == null)
        {
            return ApiResponse<bool>.Fail("RefreshToken无效");
        }
        user.SetRefreshToken(null, DateTime.MinValue);
        await _userRepository.UpdateAsync(user);
        return ApiResponse<bool>.Success(true, "Token已吊销");
    }

    public async Task<AppUser?> GetUserByIdAsync(Guid userId)
    {
        return await _userRepository.GetByIdAsync(userId);
    }

    public async Task<ApiResponse<UserProfileDto>> UpdateProfileAsync(string userId, UpdateProfileDto dto)
    {
        try
        {
            if (!Guid.TryParse(userId, out var userGuid))
                return ApiResponse<UserProfileDto>.Fail("用户ID格式错误");

            var user = await _userRepository.GetByIdAsync(userGuid);
            if (user == null)
                return ApiResponse<UserProfileDto>.Fail("用户不存在");

            // 验证邮箱格式
            if (!string.IsNullOrEmpty(dto.Email))
            {
                var emailError = FormValidator.ValidateEmail(dto.Email);
                if (emailError != null)
                    return ApiResponse<UserProfileDto>.Fail(emailError);

                // 检查邮箱是否已被其他用户使用
                var existingUsers = await _userRepository.GetAllAsync();
                var emailExists = existingUsers.Any(u => u.Email == dto.Email && u.Id != userGuid);
                if (emailExists)
                    return ApiResponse<UserProfileDto>.Fail("邮箱已被其他用户使用");
            }

            // 更新用户信息
            user.UpdateProfile(dto.NickName, dto.Email, dto.Description);
            await _userRepository.UpdateAsync(user);

            var profile = new UserProfileDto(
                user.Id,
                user.Username,
                user.NickName,
                user.Email,
                user.Avatar,
                user.Description
            );

            return ApiResponse<UserProfileDto>.Success(profile, "用户资料更新成功");
        }
        catch (Exception ex)
        {
            return ApiResponse<UserProfileDto>.Fail($"更新用户资料失败: {ex.Message}");
        }
    }

    public async Task<ApiResponse<object>> ChangePasswordAsync(string userId, ChangePasswordDto dto)
    {
        try
        {
            if (!Guid.TryParse(userId, out var userGuid))
                return ApiResponse<object>.Fail("用户ID格式错误");

            var user = await _userRepository.GetByIdAsync(userGuid);
            if (user == null)
                return ApiResponse<object>.Fail("用户不存在");

            // 验证旧密码
            if (!user.VerifyPassword(dto.OldPassword))
                return ApiResponse<object>.Fail("当前密码不正确");

            // 验证新密码格式
            var passwordError = FormValidator.ValidatePassword(dto.NewPassword);
            if (passwordError != null)
                return ApiResponse<object>.Fail(passwordError);

            // 使用UserService的修改密码方法
            var result = await _userService.ChangePasswordAsync(userGuid, dto.OldPassword, dto.NewPassword);
            if (result.IsSuccess)
            {
                return ApiResponse<object>.Success(null, "密码修改成功");
            }
            else
            {
                return ApiResponse<object>.Fail(result.Message);
            }
        }
        catch (Exception ex)
        {
            return ApiResponse<object>.Fail($"修改密码失败: {ex.Message}");
        }
    }

    public async Task<ApiResponse<object>> UpdateAvatarAsync(string userId, string avatarUrl)
    {
        try
        {
            if (!Guid.TryParse(userId, out var userGuid))
                return ApiResponse<object>.Fail("用户ID格式错误");

            var user = await _userRepository.GetByIdAsync(userGuid);
            if (user == null)
                return ApiResponse<object>.Fail("用户不存在");

            user.UpdateAvatar(avatarUrl);
            await _userRepository.UpdateAsync(user);

            return ApiResponse<object>.Success(null, "头像更新成功");
        }
        catch (Exception ex)
        {
            return ApiResponse<object>.Fail($"更新头像失败: {ex.Message}");
        }
    }
}